package utils

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"github.com/disintegration/imaging"
	"image"
	"io"
	"log"
	"os"
	"os/exec"
	"partyus_app/cos_api"
	"partyus_app/models"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

// 支持的图片和视频文件扩展名
var (
	ImageExtensions = []string{".jpg", ".jpeg", ".png", ".gif"}
	VideoExtensions = []string{".mp4", ".avi", ".mov", ".mkv"}
)

// IsValidExtension 验证文件扩展名是否为图片或视频
func IsValidExtension(filename string, extensions []string) bool {
	ext := strings.ToLower(filepath.Ext(filename))
	for _, validExt := range extensions {
		if ext == validExt {
			return true
		}
	}
	return false
}

// GenerateHashedFilename 生成基于 MD5 和时间戳的新文件名
func GenerateHashedFilename(filename string) string {
	ext := filepath.Ext(filename) // 获取文件扩展名
	name := strings.TrimSuffix(filename, ext)

	// 生成文件名的 MD5
	hash := md5.New()
	hash.Write([]byte(name))
	hashName := hex.EncodeToString(hash.Sum(nil))

	// 使用 MD5 哈希值和时间戳拼接
	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
	return fmt.Sprintf("%s_%s%s", hashName, timestamp, ext)
}

// DeleteFile 删除文件
func DeleteFile(filePath string) error {
	return os.Remove(filePath)
}

// CutPostContent 按字符截断 content 到 100 字符
func CutPostContent(postlist *[]models.Post) {
	// 检查 postlist 是否为 nil
	if postlist == nil {
		return
	}

	// 遍历每个 Post
	for i := range *postlist {
		post := &(*postlist)[i]
		// 如果 Content 长度超过 100 个字符，则截断
		if utf8.RuneCountInString(post.Content) > 100 {
			// 使用 utf8 库来截取前 100 个字符
			runes := []rune(post.Content)
			post.Content = string(runes[:100]) + "..."
		}
	}
}

func ExtractFirstFrameToCOS(videoPath, finalName string) (string, error) {
	// ffmpeg 命令参数：输出一帧到 stdout，格式为 jpeg
	cmd := exec.Command("ffmpeg", "-y", "-i", videoPath, "-vframes", "1", "-f", "image2", "-q:v", "2", "pipe:1")

	log.Println("执行命令:", strings.Join(cmd.Args, " "))

	// 获取标准输出管道
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return "", err
	}

	// 启动命令
	if err := cmd.Start(); err != nil {
		return "", err
	}

	// 读取全部图片数据
	imgData, err := io.ReadAll(stdout)
	if err != nil {
		return "", err
	}

	// 等待命令执行完毕
	if err := cmd.Wait(); err != nil {
		return "", err
	}

	// 生成 COS 对象键（路径）
	objectKey := fmt.Sprintf("pictures/%s.jpg", finalName)

	// 上传到 COS，传入图片数据的 Reader
	fileURL, err := cos_api.UploadReaderToCOS(bytes.NewReader(imgData), objectKey)
	if err != nil {
		return "", err
	}

	return fileURL, nil
}

// CompressImageToJPEG 压缩图片质量但不改变尺寸，返回 JPEG 格式的 io.Reader
func CompressImageToJPEG(r io.Reader, quality int) (io.Reader, error) {
	img, _, err := image.Decode(r)
	if err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)
	err = imaging.Encode(buf, img, imaging.JPEG, imaging.JPEGQuality(quality))
	if err != nil {
		return nil, err
	}

	return buf, nil
}
